package cn.sytton.taffe.web.flw.service.impl;

import cn.sytton.taffe.framework.util.SecurityUtil;
import cn.sytton.taffe.web.flw.entity.FormDefEntity;
import cn.sytton.taffe.web.flw.entity.FormDefStructureEntity;
import cn.sytton.taffe.web.flw.mapper.FormDefMapper;
import cn.sytton.taffe.web.flw.mapper.FormDefStructureMapper;
import cn.sytton.taffe.web.flw.service.IFormDefStructureService;
import cn.sytton.taffe.framework.base.service.BaseService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 工作流表单_结构表 服务实现类
 * </p>
 *
 * @author rock
 * @since 2023-09-27
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class FormDefStructureService extends BaseService<FormDefStructureMapper, FormDefStructureEntity> implements IFormDefStructureService {

    private final FormDefMapper formDefMapper;

    @Override
    public FormDefStructureEntity createAndActive(FormDefStructureEntity entity) {
        //保存
        FormDefStructureEntity newEntity = new FormDefStructureEntity()
                .setFormId(entity.getFormId())
                .setFormJson(entity.getFormJson())
                .setVersion(getNextVersion(entity.getFormId()));
        super.create(newEntity);
        //激活
        formDefMapper.activeStructure(new FormDefEntity()
                .setFormId(newEntity.getFormId())
                .setStructureId(newEntity.getStructureId()));

        return newEntity;
    }

    @Override
    public FormDefStructureEntity updateAndActive(FormDefStructureEntity entity) {
        //保存
        update(new LambdaUpdateWrapper<FormDefStructureEntity>()
                .set(FormDefStructureEntity::getFormJson, entity.getFormJson())
                .set(FormDefStructureEntity::getUpdatedTime, entity.newTimestamp())
                .set(FormDefStructureEntity::getUpdatedUserId, SecurityUtil.getUserId())
                .eq(FormDefStructureEntity::getStructureId, entity.getStructureId()));
        //激活
        entity = findById(entity.getStructureId());
        formDefMapper.activeStructure(new FormDefEntity()
                .setFormId(entity.getFormId())
                .setStructureId(entity.getStructureId()));

        return entity;
    }

    @Override
    public FormDefStructureEntity create(String formId) {
        FormDefStructureEntity entity = new FormDefStructureEntity()
                .setFormId(formId)
                .setVersion(getNextVersion(formId));
        create(entity);
        return entity;
    }

    @Override
    public void removeByFormIds(String... formIds) {
        Map<String, Object> params = new HashMap<>();
        for (String formId : formIds) {
            params.put("formId", formId);
            removeByMap(params);
        }
    }

    private synchronized int getNextVersion(String formId) {
        List<FormDefStructureEntity> list = list(new LambdaQueryWrapper<FormDefStructureEntity>()
                .eq(FormDefStructureEntity::getFormId, formId)
                .orderByDesc(FormDefStructureEntity::getVersion));
        if (list == null || list.size() == 0) {
            return 1;
        } else {
            return list.get(0).getVersion() + 1;
        }
    }

    @Override
    public FormDefStructureEntity active(String formId, String structureId) {
        formDefMapper.activeStructure(new FormDefEntity()
                .setFormId(formId)
                .setStructureId(structureId));
        return findById(structureId);
    }

    @Override
    public FormDefStructureEntity findByFormId(String formId) {
        FormDefEntity formDefEntity = formDefMapper.selectById(formId);
        if (formDefEntity != null) {
            FormDefStructureEntity entity = findById(formDefEntity.getStructureId());
            entity.setFormName(formDefEntity.getFormName());
            entity.setProcessDefId(formDefEntity.getProcessDefId());
            entity.setProcessDefKey(formDefEntity.getProcessDefKey());
            entity.setActive(1);
            return entity;
        } else {
            return null;
        }
    }
}
